package cn.rxls.community.service.impl;

import cn.rxls.community.entity.User;
import cn.rxls.community.enums.HouseStateEnum;
import cn.rxls.community.enums.ResultEnum;
import cn.rxls.community.enums.UserHousesStateEnum;
import cn.rxls.community.enums.UserStateEnum;
import cn.rxls.community.exception.BusinessException;
import cn.rxls.community.mapper.HousesMapper;
import cn.rxls.community.mapper.UserMapper;
import cn.rxls.community.service.LoginService;
import cn.rxls.community.util.JwtUtil;
import cn.rxls.community.vo.houses.HousesVO;
import cn.rxls.community.vo.login.LoginHouseVO;
import cn.rxls.community.vo.login.LoginVO;
import cn.rxls.community.vo.login.WxChat;
import cn.rxls.community.vo.user.UserVO;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.*;

/**
 * 登录/登出
 */

@Service("loginService")
@Transactional(rollbackFor = Exception.class)
public class LoginServiceImpl implements LoginService {
    @Resource
    RestTemplate restTemplate;

    @Resource
    UserMapper userMapper;

    @Resource
    HousesMapper housesMapper;


    @Value("${rxsq.wechat.appid}")
    private String APP_ID; //appid

    @Value("${rxsq.wechat.secret}")
    private String SECRET; //密钥
    private static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";


    /**
     * 登录
     *
     * @param code 授权码
     * @return 用户信息
     */
    @Override
    public LoginVO login(String code) {
        //获取openid
        String openid = getOpenid(code);
        if (openid == null || openid.equals("")) {
            throw new BusinessException(ResultEnum.ERROR_AUTHORIZED);
        }

        //返回登录信息的VO
        LoginVO loginVO = new LoginVO();

        //查询用户信息
        UserVO userInfo = userMapper.selectByOpenid(openid);

        //查询的用户信息不为null,则进行开始封装登录信息
        if (userInfo != null) {
            BeanUtils.copyProperties(userInfo, loginVO.getUser());
        }

        //如果查询的用户信息为null，则注册
        Optional.ofNullable(userInfo == null ? true : null).ifPresent(s -> {
            //封装登录信息
            BeanUtils.copyProperties(this.enroll(openid), loginVO.getUser());
        });

        //查询用户拥有的房屋信息
        List<LoginHouseVO> housesVOS = housesMapper.selectByUserId(loginVO.getUser().getUserId(),
                HouseStateEnum.OCCUPIED.code,
                UserHousesStateEnum.NORMAL.code);

        loginVO.setHouses(housesVOS);

        //生成token,并存入
        Map<String, Object> info = new HashMap<>();
        info.put("uid", loginVO.getUser().getUserId());
        info.put("username", loginVO.getUser().getUsername());
        String token = JwtUtil.createToken(info);
        loginVO.setToken(token);

        //返回登录信息
        return loginVO;
    }

    /**
     * 登出
     *
     * @param uid 用户id
     */
    @Override
    public void LoginOut(String uid) {

    }


    //远程请求微信，获取openid 用户唯一标识
    public String getOpenid(String code) {
        //请求路径
        String url = WX_LOGIN + "?appid=" + APP_ID
                + "&secret=" + SECRET
                + "&js_code=" + code
                + "&grant_type=authorization_code";

        //远程请求微信 ，请求微信授权
        String forObject = restTemplate.getForObject(url, String.class);
        System.err.println(forObject);
        System.err.println(url);
        WxChat wxChat = JSON.parseObject(forObject, WxChat.class);
        return Objects.isNull(wxChat) ? null : wxChat.getOpenid();
    }

    /**
     * 注册
     *
     * @param openid 微信唯一标识
     * @return 用户信息
     */
    @Override
    public UserVO enroll(String openid) {
        User user = new User();
        UserVO userInfo = new UserVO();
        //默认用户名
        user.setUsername("软星" + System.currentTimeMillis());
        user.setAvatar("https://www.lyzhnb.top/waxl/QQ%E5%9B%BE%E7%89%8720240314093823.jpg");
        user.setOpenid(openid);
        user.setState(UserStateEnum.NORMAL.code);
        userMapper.insert(user);
        if (user.getUserId() == null) {
            throw new BusinessException(ResultEnum.ERROR_ENROLL);
        }
        BeanUtils.copyProperties(user, userInfo);
        return userInfo;
    }
}
